package cn.jji8.createX.function.fill.canPlaceBlock;

import cn.jji8.createX.build.Build;
import cn.jji8.createX.function.fill.FillManger;
import cn.jji8.createX.build.LoadRes;
import cn.jji8.createX.slowPlaceBlock.CanPlaceBlock;
import cn.jji8.createX.slowPlaceBlock.SlowPlaceBlockManger;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.Objects;

/**
 * 填充的CanPlaceBlock
 * */
public class FillCanPlaceBlock implements CanPlaceBlock {
    //必须有挖掘工具才可以挖掘
    public static boolean UsingMiningTools = true;
    //需要材料
    public static boolean MaterialsAreNeeded = true;
    //被挖方块掉落
    public static boolean TheExcavatedBlockFalls = true;

    /*      执行填充的玩家      */
    final Player player;

    /*        方块     */
    final Material type;

    /*        填充位置    结束位置   现在位置           */
    final Location location1;
    final Location location2;
    Location locationNow;

    /*   */
    final FillManger fillManger;
    /*    第一次无材料的时间  */
    long tiem =0;

    /*                       填充状态控制器                      */
    final FillCanPlaceBlockState fillCanPlaceBlockState;
    /*即将发送的消息*/
    String sendMessage = null;
    /*                               玩家             方块            开始位置              结束位置             现在位置                             填充状态控制器*/
    @SuppressWarnings("unused")
    private FillCanPlaceBlock(Player player, Material type, Location location1, Location location2, Location locationNow, FillCanPlaceBlockState fillCanPlaceBlockState, FillManger fillManger) {
        this.player = player;
        this.type = type;
        this.location1 = location1;
        this.location2 = location2;
        this.locationNow = locationNow;
        this.fillCanPlaceBlockState = fillCanPlaceBlockState;
        this.fillManger = fillManger;
    }

    /**
     * 用于在指定位置放置方块的方法
     *
     * @return 下一个需要填充的方块
     */
    @Override
    public CanPlaceBlock place(){
        CanPlaceBlock fillCanPlaceBlock = place(0);
        if(fillCanPlaceBlock==null){
            fillCanPlaceBlockState.setComplete(true);
        }
        if(sendMessage!=null){
            SlowPlaceBlockManger.sendMessage(player,sendMessage);
            sendMessage = null;
        }
       return fillCanPlaceBlock;
    }
    /**
     * 用于在指定位置放置方块的方法
     * @param  recursion 递归的成数
     * @return 下一个需要填充的方块
     */
    public FillCanPlaceBlock place(int recursion) {
        //被取消
        if(fillCanPlaceBlockState.isCancel()){
            return null;
        }
        //领地权限
        if(!LoadRes.isCanBuild(player,locationNow)){
            if(tiem==0){
                tiem = System.currentTimeMillis();
            }
            if(tiem+1000*10<System.currentTimeMillis()){
                return null;
            }
            sendMessage = "§d你没有在("+locationNow.getBlockX()+" "+locationNow.getBlockY()+" "+locationNow.getBlockZ()+")位置建造的权限! "+((tiem+1000*10-System.currentTimeMillis())/1000)+"秒后自动取消填充。";
            return this;
        }
        //计算进度
        int Completed=locationNow.getBlockX()-location1.getBlockX()+
                (locationNow.getBlockZ()-location1.getBlockZ())*(location2.getBlockX()-location1.getBlockX()+1)+
                (locationNow.getBlockY()-location1.getBlockY())*(location2.getBlockZ()-location1.getBlockZ()+1)*(location2.getBlockX()-location1.getBlockX()+1);

        int whole=(location2.getBlockX()-location1.getBlockX()+1)*(location2.getBlockZ()-location1.getBlockZ()+1)*(location2.getBlockY()-location1.getBlockY()+1);
        //判断是否还有挖掘工具
        ItemStack itemStack = fillManger.getMiningTools();
        //挖掘选项
        if(UsingMiningTools){
            if(Material.AIR.equals(itemStack.getType())){
                if(tiem==0){
                    tiem = System.currentTimeMillis();
                }
                if(tiem+1000*60<System.currentTimeMillis()){
                    return null;
                }
                sendMessage = "§d填充正在进行,已完成：§e"+Completed+"§d/§a"+whole+"  §l§c没有挖掘工具！ 请补充挖掘工具。"+((tiem+1000*60-System.currentTimeMillis())/1000)+"秒后自动取消填充。";
                return this;
            }
        }

        //给玩家反馈
        sendMessage = "§d填充正在进行,已完成：§e"+Completed+"§d/§a"+whole;

        //不填充相同的方块
        if((!type.equals(locationNow.getBlock().getType()))&(!Material.BEDROCK.equals(locationNow.getBlock().getType()))){
            //扣材料选项
            if(MaterialsAreNeeded){
                //扣材料
                if(!fillManger.buckle(type)){
                    if(tiem==0){
                        tiem = System.currentTimeMillis();
                    }
                    if(tiem+1000*60<System.currentTimeMillis()){
                        return null;
                    }
                    sendMessage = "§d填充正在进行,已完成：§e"+Completed+"§d/§a"+whole+"  §l§c材料不足！ 请补充材料。"+((tiem+1000*60-System.currentTimeMillis())/1000)+"秒后自动取消填充。";
                    return this;
                }
            }

            ItemStack itemStack1 = fillManger.getMiningTools();
            //显示破坏效果
            fillCanPlaceBlockState.playEffectSTEP_SOUND(locationNow);
            //如果需要挖掉方块，如果不是空气
            if(!locationNow.getBlock().getType().equals(Material.AIR)){
                //判断是否可以挖掘
                if (!Build.isPlayerCanBreak(locationNow.getBlock(),player)) {
                    sendMessage = "§d你在("+locationNow.getBlockX()+" "+locationNow.getBlockY()+" "+locationNow.getBlockZ()+")位置的挖掘操作被拒绝! ";
                    return null;
                }
                //挖掉之前的方块
                if(TheExcavatedBlockFalls){
                    locationNow.getBlock().breakNaturally(itemStack1);
                }
                //减少工具耐久
                ItemMeta itemMeta = itemStack1.getItemMeta();
                if(itemMeta instanceof Damageable){
                    Damageable damageable = ((Damageable)itemMeta);
                    damageable.setDamage(damageable.getDamage()+1);
                    //如果坏掉了，就设置成空气
                    if(damageable.getDamage()>itemStack1.getType().getMaxDurability()){
                        fillManger.setMiningTools(new ItemStack(Material.AIR));
                    }
                }
                itemStack1.setItemMeta(itemMeta);
                //刷新显示的工具
                fillManger.refreshMiningToolsSSSSS();
            }
            //判断是否可以放置
            if (!Build.isPlayerCanPlace(locationNow.getBlock(),locationNow.getBlock(),new ItemStack(type),player)) {
                sendMessage = "§d你在("+locationNow.getBlockX()+" "+locationNow.getBlockY()+" "+locationNow.getBlockZ()+")位置的放置操作被拒绝! ";
                return null;
            }
            //填充方块
            locationNow.getBlock().setType(type);
            return next();
        }
        FillCanPlaceBlock fillCanPlaceBlock = next();
        if(fillCanPlaceBlock==null){
            return null;
        }
        //防止炸栈
        if(recursion<100){
            //直接填充下一个方块
            return fillCanPlaceBlock.place(++recursion);
        }
        return this;
    }

    //将自己设置到下一个位置
    private FillCanPlaceBlock next(){
        tiem = 0;
        if(locationNow.getBlockX()<location2.getBlockX()){
            locationNow = new Location(locationNow.getWorld(),locationNow.getBlockX()+1,locationNow.getBlockY(),locationNow.getBlockZ());
            return this;
        }
        locationNow.setX(location1.getBlockX());
        if(locationNow.getBlockZ()<location2.getBlockZ()){
            locationNow = new Location(locationNow.getWorld(),locationNow.getBlockX(),locationNow.getBlockY(),locationNow.getBlockZ()+1);
            return this;
        }
        locationNow.setZ(location1.getBlockZ());
        if(locationNow.getBlockY()<location2.getBlockY()){
            locationNow = new Location(locationNow.getWorld(),locationNow.getBlockX(),locationNow.getBlockY()+1,locationNow.getBlockZ());
            return this;
        }
        return null;
    }

    public static FillCanPlaceBlockState fill(Player player, Material type, Location location1, Location location2,FillManger fillManger){
        if(!Objects.requireNonNull(location1.getWorld()).equals(location2.getWorld())){
            return new FillCanPlaceBlockState(player,true,true);
        }
        World world = location1.getWorld();
        int x1=location1.getBlockX(),y1=location1.getBlockY(),z1=location1.getBlockZ(),x2=location2.getBlockX(),y2=location2.getBlockY(),z2=location2.getBlockZ();
        if(x1>x2){
            int i = x1;
            x1=x2;
            x2=i;
        }
        if(y1>y2){
            int i = y1;
            y1=y2;
            y2=i;
        }
        if(z1>z2){
            int i = z1;
            z1=z2;
            z2=i;
        }
        FillCanPlaceBlockState fillCanPlaceBlockState = new FillCanPlaceBlockState(player,false,false);
        FillCanPlaceBlock fillCanPlaceBlock = new FillCanPlaceBlock(player,type,new Location(world,x1,y1,z1),new Location(world,x2,y2,z2),new Location(world,x1,y1,z1),fillCanPlaceBlockState,fillManger);
        SlowPlaceBlockManger.addSoonPlaceBlock(fillCanPlaceBlock);
        return fillCanPlaceBlockState;
    }
}
